/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * TetrisTest.java
 *
 * Created on Sep 18, 2009, 11:38:23 AM
 */
package sirtet.tetris.program;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;
import javax.swing.JOptionPane;
import sirtet.ControlledPlayer;
import sirtet.Player;
import sirtet.gui.KeyboardPlayer;
import sirtet.netplay.Communicator;
import sirtet.netplay.SynchronizedPlayer;
import sirtet.netplay.server.BounceServer;
import sirtet.netplay.server.Receptionist;
import sirtet.tetris.BattlingTetrisBoard;
import sirtet.tetris.FallEnforcer;
import sirtet.tetris.RandomPieceProvider;
import sirtet.tetris.ActionBattlingAttacker;
import sirtet.tetris.RemotePieceProvider;
import sirtet.tetris.TetrisAction;
import sirtet.tetris.TetrisBoard;
import sirtet.tetris.TetrisQualifierRoomFactory;
import sirtet.tetris.gui.NextPiecePanel;
import sirtet.tetris.gui.TetrisBoardPanel;
import sirtet.tetris.gui.TetrisGamePanel;

/**
 *
 * @author guangwei.zhu
 */
public class TetrisClient extends javax.swing.JFrame {

    private Receptionist gate;

    /** Creates new form TetrisTest */
    public TetrisClient() throws Exception {
        this.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        testClient();
    }

    public void testQualifier() throws Exception {
        this.setLayout(new GridLayout(1, 1));

        // Next piece panel
        NextPiecePanel nextPiecePanel1 = new NextPiecePanel();
        nextPiecePanel1.setVisible(true);
        nextPiecePanel1.setPreferredSize(new Dimension(140, 0));

        // TetrisBoard and its panel
        TetrisBoard board1 = new TetrisBoard(20, 30);
        TetrisBoardPanel boardPanel1 = new TetrisBoardPanel(board1);
        TetrisGamePanel mainPanel1 = new TetrisGamePanel(boardPanel1, nextPiecePanel1);

        // Let NextPiecePanel know when to draw new pieces
        board1.addBoardListener(nextPiecePanel1);

        // KeyboardPlayer - keyboard input
        KeyboardPlayer player1 = new KeyboardPlayer("Player" + (new Random().nextInt() % 1000), TetrisQualifierRoomFactory.GAMETYPE);
        mainPanel1.setFocusable(false);
        player1.registerKeyCommand(KeyEvent.VK_S, TetrisAction.FALL);
        player1.registerKeyCommand(KeyEvent.VK_A, TetrisAction.LEFT);
        player1.registerKeyCommand(KeyEvent.VK_D, TetrisAction.RIGHT);
        player1.registerKeyCommand(KeyEvent.VK_W, TetrisAction.ROTATE);

        // Relate the KeyboardPlayer to this JForm
        this.addKeyListener(player1);

        SynchronizedPlayer player1N;
        // Communicator for Player 1
        Communicator comm1 = new Communicator(JOptionPane.showInputDialog("Enter server address:"), 9462);

        // Add network layer
        player1N = new SynchronizedPlayer(player1, comm1);
        board1.registerPlayer(player1N);

        // New piece provider
        board1.setPieceProvider(new RemotePieceProvider(player1N));

        comm1.activate();
        player1N.setReady(true);

        board1.start();

        this.add(mainPanel1);
    }

    public void testClient() throws Exception {
        this.setLayout(new GridLayout(1, 1));

        // Next piece panel
        NextPiecePanel nextPiecePanel1 = new NextPiecePanel();
        nextPiecePanel1.setVisible(true);
        nextPiecePanel1.setPreferredSize(new Dimension(140, 0));

        // TetrisBoard and its panel
        BattlingTetrisBoard board1 = new BattlingTetrisBoard(20, 30);
        TetrisBoardPanel boardPanel1 = new TetrisBoardPanel(board1);
        TetrisGamePanel mainPanel1 = new TetrisGamePanel(boardPanel1, nextPiecePanel1);

        // Let NextPiecePanel know when to draw new pieces
        board1.addBoardListener(nextPiecePanel1);

        // KeyboardPlayer - keyboard input
        KeyboardPlayer player1 = new KeyboardPlayer("Player" + (new Random().nextInt() % 1000), TetrisBoard.GAMETYPE);
        mainPanel1.setFocusable(false);
        player1.registerKeyCommand(KeyEvent.VK_S, TetrisAction.FALL);
        player1.registerKeyCommand(KeyEvent.VK_A, TetrisAction.LEFT);
        player1.registerKeyCommand(KeyEvent.VK_D, TetrisAction.RIGHT);
        player1.registerKeyCommand(KeyEvent.VK_W, TetrisAction.ROTATE);

        // Relate the KeyboardPlayer to this JForm
        this.addKeyListener(player1);

        SynchronizedPlayer player1N;
        // Communicator for Player 1
        Communicator comm1 = new Communicator(JOptionPane.showInputDialog("Enter server address:"), 9462);

        // Add network layer
        player1N = new SynchronizedPlayer(player1, comm1);
        board1.registerPlayer(player1N);

        // New piece provider
        board1.setPieceProvider(new RemotePieceProvider(player1N));

        // Play against each other
        new ActionBattlingAttacker(player1N).addAttackTarget(board1);

        comm1.activate();
        player1N.setReady(true);

        board1.start();

        this.add(mainPanel1);
    }

    public void testLocal() throws Exception {
        // Initialize server side
        gate = new Receptionist(8465);
        gate.addHandler(new BounceServer(0));
        gate.beginWait();

        this.setLayout(new GridLayout(1, 2));

        // Next piece panel
        NextPiecePanel nextPiecePanel1 = new NextPiecePanel();
        nextPiecePanel1.setVisible(true);
        nextPiecePanel1.setPreferredSize(new Dimension(140, 0));

        // TetrisBoard and its panel
        BattlingTetrisBoard board1 = new BattlingTetrisBoard(20, 30);
        TetrisBoardPanel boardPanel1 = new TetrisBoardPanel(board1);
        TetrisGamePanel mainPanel1 = new TetrisGamePanel(boardPanel1, nextPiecePanel1);

        // Let NextPiecePanel know when to draw new pieces
        board1.addBoardListener(nextPiecePanel1);

        // New piece provider
        board1.setPieceProvider(new RandomPieceProvider());

        // KeyboardPlayer - keyboard input
        KeyboardPlayer player1 = new KeyboardPlayer("guangwei.zhu", TetrisBoard.GAMETYPE);
        mainPanel1.setFocusable(false);
        player1.registerKeyCommand(KeyEvent.VK_S, TetrisAction.FALL);
        player1.registerKeyCommand(KeyEvent.VK_A, TetrisAction.LEFT);
        player1.registerKeyCommand(KeyEvent.VK_D, TetrisAction.RIGHT);
        player1.registerKeyCommand(KeyEvent.VK_W, TetrisAction.ROTATE);

        // Relate the KeyboardPlayer to this JForm
        this.addKeyListener(player1);

        Player player1N;
        // Add network layer
        player1N = new ControlledPlayer(player1, 500);
        board1.registerPlayer(player1N);


        // Next piece panel
        NextPiecePanel nextPiecePanel2 = new NextPiecePanel();
        nextPiecePanel2.setVisible(true);
        nextPiecePanel2.setPreferredSize(new Dimension(140, 0));

        // TetrisBoard and its panel
        BattlingTetrisBoard board2 = new BattlingTetrisBoard(20, 30);
        TetrisBoardPanel boardPanel2 = new TetrisBoardPanel(board2);
        TetrisGamePanel mainPanel2 = new TetrisGamePanel(boardPanel2, nextPiecePanel2);

        // Let NedataxtPiecePanel know when to draw new pieces
        board2.addBoardListener(nextPiecePanel2);

        // New piece provider
        board2.setPieceProvider(new RandomPieceProvider());

        // KeyboardPlayer - keyboard input
        KeyboardPlayer player2 = new KeyboardPlayer("guangwei.zhu", TetrisBoard.GAMETYPE);
        mainPanel2.setFocusable(false);
        player2.registerKeyCommand(KeyEvent.VK_DOWN, TetrisAction.FALL);
        player2.registerKeyCommand(KeyEvent.VK_LEFT, TetrisAction.LEFT);
        player2.registerKeyCommand(KeyEvent.VK_RIGHT, TetrisAction.RIGHT);
        player2.registerKeyCommand(KeyEvent.VK_UP, TetrisAction.ROTATE);

        // Relate the KeyboardPlayer to this JForm
        this.addKeyListener(player2);

        SynchronizedPlayer player2N;
        // Add network layer
        player2N = new SynchronizedPlayer(player2, new Communicator("localhost", 8465));
        board2.registerPlayer(player2N);

        // Play against each other
        board1.addAttackTarget(board2);
        board2.addAttackTarget(board1);

        // Register a fall enforcer
        board1.registerPlayer(new FallEnforcer(100));
        board2.registerPlayer(new FallEnforcer(500));

        // Start the board game
        while (!player1N.ready() || !player2N.ready()) {
        }
        board1.start();
        board2.start();

        this.add(mainPanel1);
        this.add(mainPanel2);

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) throws Exception {
        TetrisClient client = new TetrisClient();

        client.setSize(540, 600);
        client.setVisible(true);
    }
    // Variables declaration - do not modify
    // End of variables declaration
}
